package com.moon.cloud.common.utils;

import java.util.Collection;
import java.util.UUID;
import java.util.regex.Pattern;

/**
 * 字符串工具类
 */
public class StringUtils {

    private static final Pattern MOBILE_PATTERN = Pattern.compile("^1[3-9]\\d{9}$");
    private static final Pattern EMAIL_PATTERN = Pattern.compile("^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)+$");
    private static final Pattern ID_CARD_PATTERN = Pattern.compile("^[1-9]\\d{5}(18|19|20)\\d{2}((0[1-9])|(1[0-2]))(([0-2][1-9])|10|20|30|31)\\d{3}[0-9Xx]$");

    /**
     * 判断字符串是否为空
     *
     * @param str 待判断的字符串
     * @return 如果字符串为null或长度为0则返回true，否则返回false
     */
    public static boolean isEmpty(CharSequence str) {
        return str == null || str.isEmpty();
    }

    /**
     * 判断字符串是否不为空
     *
     * @param str 待判断的字符串
     * @return 如果字符串不为null且长度大于0则返回true，否则返回false
     */
    public static boolean isNotEmpty(CharSequence str) {
        return !isEmpty(str);
    }

    /**
     * 判断字符串是否为空白（null、空字符串、空格、制表符等）
     *
     * @param str 待判断的字符串
     * @return 如果字符串为null、空字符串或只包含空白字符则返回true，否则返回false
     */
    public static boolean isBlank(CharSequence str) {
        if (isEmpty(str)) {
            return true;
        }
        for (int i = 0; i < str.length(); i++) {
            if (!Character.isWhitespace(str.charAt(i))) {
                return false;
            }
        }
        return true;
    }

    /**
     * 判断字符串是否不为空白
     *
     * @param str 待判断的字符串
     * @return 如果字符串不为null、不是空字符串且包含非空白字符则返回true，否则返回false
     */
    public static boolean isNotBlank(CharSequence str) {
        return !isBlank(str);
    }

    /**
     * 去除首尾空格
     *
     * @param str 待处理的字符串
     * @return 去除首尾空格后的字符串，如果原字符串为null则返回null
     */
    public static String trim(String str) {
        return str == null ? null : str.trim();
    }

    /**
     * 去除所有空格
     *
     * @param str 待处理的字符串
     * @return 去除所有空格后的字符串，如果原字符串为空则返回原字符串
     */
    public static String trimAll(String str) {
        return isEmpty(str) ? str : str.replaceAll("\\s+", "");
    }

    /**
     * 首字母大写
     *
     * @param str 待处理的字符串
     * @return 首字母大写后的字符串，如果原字符串为空则返回原字符串
     */
    public static String capitalize(String str) {
        if (isEmpty(str)) {
            return str;
        }
        return str.substring(0, 1).toUpperCase() + str.substring(1);
    }

    /**
     * 首字母小写
     *
     * @param str 待处理的字符串
     * @return 首字母小写后的字符串，如果原字符串为空则返回原字符串
     */
    public static String uncapitalize(String str) {
        if (isEmpty(str)) {
            return str;
        }
        return str.substring(0, 1).toLowerCase() + str.substring(1);
    }

    /**
     * 驼峰转下划线
     *
     * @param str 待转换的驼峰字符串
     * @return 转换为下划线格式的字符串，如果原字符串为空则返回原字符串
     */
    public static String camelToUnderline(String str) {
        if (isEmpty(str)) {
            return str;
        }
        return str.replaceAll("([A-Z])", "_$1").toLowerCase().replaceFirst("^_", "");
    }

    /**
     * 下划线转驼峰
     *
     * @param str 待转换的下划线字符串
     * @return 转换为驼峰格式的字符串，如果原字符串为空则返回原字符串
     */
    public static String underlineToCamel(String str) {
        if (isEmpty(str)) {
            return str;
        }
        StringBuilder result = new StringBuilder();
        String[] parts = str.split("_");
        for (int i = 0; i < parts.length; i++) {
            if (i == 0) {
                result.append(parts[i].toLowerCase());
            } else {
                result.append(capitalize(parts[i].toLowerCase()));
            }
        }
        return result.toString();
    }

    /**
     * 字符串拼接（使用分隔符）
     *
     * @param collection 待拼接的集合
     * @param separator 分隔符
     * @return 拼接后的字符串
     */
    public static String join(Collection<?> collection, String separator) {
        if (collection == null || collection.isEmpty()) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        int i = 0;
        for (Object obj : collection) {
            if (i > 0) {
                sb.append(separator);
            }
            sb.append(obj);
            i++;
        }
        return sb.toString();
    }

    /**
     * 字符串拼接（数组）
     *
     * @param array 待拼接的数组
     * @param separator 分隔符
     * @return 拼接后的字符串
     */
    public static String join(Object[] array, String separator) {
        if (array == null || array.length == 0) {
            return "";
        }
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < array.length; i++) {
            if (i > 0) {
                sb.append(separator);
            }
            sb.append(array[i]);
        }
        return sb.toString();
    }

    /**
     * 判断字符串是否包含（忽略大小写）
     *
     * @param str 主字符串
     * @param searchStr 要查找的字符串
     * @return 如果主字符串包含要查找的字符串（忽略大小写）则返回true，否则返回false
     */
    public static boolean containsIgnoreCase(String str, String searchStr) {
        if (str == null || searchStr == null) {
            return false;
        }
        return str.toLowerCase().contains(searchStr.toLowerCase());
    }

    /**
     * 生成 UUID（去除横杠）
     *
     * @return 去除横杠的UUID字符串
     */
    public static String uuid() {
        return UUID.randomUUID().toString().replace("-", "");
    }

    /**
     * 生成指定长度的随机字符串（数字+字母）
     *
     * @param length 随机字符串长度
     * @return 指定长度的随机字符串
     */
    public static String randomString(int length) {
        String chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789";
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            int index = (int) (Math.random() * chars.length());
            sb.append(chars.charAt(index));
        }
        return sb.toString();
    }

    /**
     * 生成指定长度的随机数字字符串
     *
     * @param length 随机数字字符串长度
     * @return 指定长度的随机数字字符串
     */
    public static String randomNumber(int length) {
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < length; i++) {
            sb.append((int) (Math.random() * 10));
        }
        return sb.toString();
    }

    /**
     * 手机号脱敏（135****8888）
     *
     * @param mobile 手机号
     * @return 脱敏后的手机号，如果原手机号不符合规范则返回原手机号
     */
    public static String maskMobile(String mobile) {
        if (isEmpty(mobile) || mobile.length() != 11) {
            return mobile;
        }
        return mobile.substring(0, 3) + "****" + mobile.substring(7);
    }

    /**
     * 身份证号脱敏（110101****1234）
     *
     * @param idCard 身份证号
     * @return 脱敏后的身份证号，如果原身份证号不符合规范则返回原身份证号
     */
    public static String maskIdCard(String idCard) {
        if (isEmpty(idCard) || idCard.length() < 10) {
            return idCard;
        }
        return idCard.substring(0, 6) + "****" + idCard.substring(idCard.length() - 4);
    }

    /**
     * 邮箱脱敏（abc***@qq.com）
     *
     * @param email 邮箱地址
     * @return 脱敏后的邮箱地址，如果原邮箱不符合规范则返回原邮箱地址
     */
    public static String maskEmail(String email) {
        if (isEmpty(email) || !email.contains("@")) {
            return email;
        }
        String[] parts = email.split("@");
        String prefix = parts[0];
        if (prefix.length() <= 3) {
            return prefix.charAt(0) + "***@" + parts[1];
        }
        return prefix.substring(0, 3) + "***@" + parts[1];
    }

    /**
     * 验证手机号格式
     *
     * @param mobile 手机号
     * @return 如果手机号格式正确返回true，否则返回false
     */
    public static boolean isMobile(String mobile) {
        return isNotEmpty(mobile) && MOBILE_PATTERN.matcher(mobile).matches();
    }

    /**
     * 验证邮箱格式
     *
     * @param email 邮箱地址
     * @return 如果邮箱格式正确返回true，否则返回false
     */
    public static boolean isEmail(String email) {
        return isNotEmpty(email) && EMAIL_PATTERN.matcher(email).matches();
    }

    /**
     * 验证身份证号格式
     *
     * @param idCard 身份证号
     * @return 如果身份证号格式正确返回true，否则返回false
     */
    public static boolean isIdCard(String idCard) {
        return isNotEmpty(idCard) && ID_CARD_PATTERN.matcher(idCard).matches();
    }

    /**
     * 默认值处理（如果为空返回默认值）
     *
     * @param str 待处理的字符串
     * @param defaultValue 默认值
     * @return 如果原字符串为空则返回默认值，否则返回原字符串
     */
    public static String defaultIfEmpty(String str, String defaultValue) {
        return isEmpty(str) ? defaultValue : str;
    }

    /**
     * 默认值处理（如果为空白返回默认值）
     *
     * @param str 待处理的字符串
     * @param defaultValue 默认值
     * @return 如果原字符串为空白则返回默认值，否则返回原字符串
     */
    public static String defaultIfBlank(String str, String defaultValue) {
        return isBlank(str) ? defaultValue : str;
    }

    /**
     * 截取字符串（超出长度添加省略号）
     *
     * @param str 待处理的字符串
     * @param maxLength 最大长度
     * @return 如果原字符串长度超过最大长度则截取并在末尾添加省略号，否则返回原字符串
     */
    public static String ellipsis(String str, int maxLength) {
        if (isEmpty(str) || str.length() <= maxLength) {
            return str;
        }
        return str.substring(0, maxLength) + "...";
    }

    /**
     * 判断字符串是否为数字
     *
     * @param str 待判断的字符串
     * @return 如果字符串是数字格式则返回true，否则返回false
     */
    public static boolean isNumeric(String str) {
        if (isEmpty(str)) {
            return false;
        }
        return str.matches("-?\\d+(\\.\\d+)?");
    }

    /**
     * 补齐字符串（左侧补0）
     *
     * @param str 待处理的字符串
     * @param length 目标长度
     * @param padChar 填充字符
     * @return 左侧补齐后的字符串
     */
    public static String padLeft(String str, int length, char padChar) {
        if (str == null) {
            str = "";
        }
        if (str.length() >= length) {
            return str;
        }
        return String.valueOf(padChar).repeat(length - str.length()) +
                str;
    }

    /**
     * 补齐字符串（右侧补0）
     *
     * @param str 待处理的字符串
     * @param length 目标长度
     * @param padChar 填充字符
     * @return 右侧补齐后的字符串
     */
    public static String padRight(String str, int length, char padChar) {
        if (str == null) {
            str = "";
        }
        if (str.length() >= length) {
            return str;
        }
        return str + String.valueOf(padChar).repeat(length - str.length());
    }
}
